package com.xinxing.learning.batch.param.config;

import com.xinxing.learning.batch.common.SyncConstants;
import com.xinxing.learning.batch.entity.User;
import com.xinxing.learning.batch.param.listener.ParamJobEndListener;
import com.xinxing.learning.batch.param.step.ParamItemProcessor;
import com.xinxing.learning.batch.param.step.ParamItemReader;
import com.xinxing.learning.batch.param.step.ParamItemWriter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableBatchProcessing
public class ParamBatchConfig {
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Bean
    @StepScope
    public ItemReader paraItemReader(@Value("#{stepExecution}") StepExecution stepExecution,
                                     @Value("#{jobParameters['time']}") Long timeParam) {
        ParamItemReader paramItemReader = new ParamItemReader();
        Map<String, Object> params = new HashMap<>();
        params.put(SyncConstants.PASS_PARAM_DATETIME, new Date(timeParam));
        paramItemReader.setParams(params);
        paramItemReader.setStepExecution(stepExecution);
        return paramItemReader;
    }

    @Bean
    public ItemProcessor paramItemProcessor() {
        return new ParamItemProcessor();
    }

    @Bean
    public ItemWriter paramItemWriter() {
        return new ParamItemWriter();
    }

    @Bean
    public JobExecutionListener paramJobListener() {
        return new ParamJobEndListener();
    }

    @Bean
    public Step paramStep(ItemReader paramItemReader, ItemProcessor paramItemProcessor, ItemWriter paramItemWriter) {
        String funcName = Thread.currentThread().getStackTrace()[0].getMethodName();
        return stepBuilderFactory.get(funcName)
                .<User, User>chunk(10)
                .reader(paramItemReader)
                .processor(paramItemProcessor)
                .writer(paramItemWriter)
                .build();
    }

    @Bean
    public Job paramJob(Step paramStep, JobExecutionListener paramJobListener) {
        String funcName = Thread.currentThread().getStackTrace()[0].getMethodName();
        return jobBuilderFactory.get(funcName)
                .listener(paramJobListener)
                .flow(paramStep)
                .end().build();
    }
}
